﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.UI;

namespace Nirvana
{
    /// <summary>
    /// 控制slider的进度做平滑动效
    /// </summary>
    [AddComponentMenu("Nirvana/UI/Bind/Variable Bind Slider")]
    [RequireComponent(typeof(Slider))]
    public sealed class UIVariableBindSlider : UIVariableBind
    {
        private static Logger logger = LogSystem.GetLogger("UIVariableBindSlider");
        private enum TweenType
        {
            IncreaseOnly,
            DecreaseOnly,
            DoubleWay
        }
        [SerializeField]
        [VariableName(UIVariableType.Float)]
        private string valueBind;

        [SerializeField]
        private float tweenSpeed;

        [SerializeField]
        private TweenType tweenType;
        private Slider _slider;
        private UIVariable _variable;
        private float sliderValue;
        private bool IsNeedTween;

        public float TweenSpeed
        {
            get
            {
                return this.tweenSpeed;
            }
            set
            {
                this.tweenSpeed = value;
            }
        }

        private void Awake()
        {
            this.Binds();
            this._slider = base.GetComponent<Slider>();
            if (this._slider == null)
            {
                return;
            }
        }

        private void Update()
        {
            if (this.IsNeedTween && this.tweenSpeed > 0f && !Mathf.Approximately(this._slider.value, this.sliderValue))
            {
                switch (this.tweenType)
                {
                    case TweenType.IncreaseOnly:
                        this.IncreaseOnly();
                        break;
                    case TweenType.DecreaseOnly:
                        this.DecreaseOnly();
                        break;
                    case TweenType.DoubleWay:
                        this.DoubleWay();
                        break;
                }
            }
        }

        protected override void BindVariables()
        {
            Assert.IsNull<UIVariable>(this._variable);
            if (!string.IsNullOrEmpty(this.valueBind))
            {
                this._variable = base.FindVariable(this.valueBind);
                if (this._variable == null)
                {
                    UIVariableBindSlider.logger.LogWarning("{0} can not find a variable {1}", new object[]
                    {
                        base.name,
                        this.valueBind
                    });
                }
                else
                {
                    this._variable.OnValueInitialized += this.OnValueInitialized;
                    this._variable.OnValueChanged += this.OnValueChanged;
                    this._variable.Add(this);
                    this.OnValueInitialized();
                }
            }
        }

        protected override void UnbindVariables()
        {
            if (this._variable != null)
            {
                this._variable.OnValueInitialized -= this.OnValueInitialized;
                this._variable.OnValueChanged -= this.OnValueChanged;
                this._variable.Remove(this);
                this._variable = null;
            }
        }


        private  void OnValueInitialized()
        {
            if (this._slider == null)
            {
                this._slider = base.GetComponent<Slider>();
            }
            if (this._slider != null)
            {
                this.sliderValue = this._variable.GetFloat();
                this._slider.value = this.sliderValue;
                this.IsNeedTween = false;
            }
        }

        private void OnValueChanged()
        {
            if (this._slider == null)
            {
                this._slider = base.GetComponent<Slider>();
            }
            if (this._slider != null)
            {
                float @float = this._variable.GetFloat();
                if (this.tweenSpeed > 0f && Application.isPlaying)
                {
                    this.sliderValue = @float;
                    this.IsNeedTween = true;
                }
                else
                {
                    this.sliderValue = @float;
                    this._slider.value = @float;
                    this.IsNeedTween = false;
                }
            }
        }

        private void IncreaseOnly()
        {
            if (this.sliderValue > this._slider.value)
            {
                this.DoubleWay();
                return;
            }
            float num = this.tweenSpeed * Time.deltaTime;
            float num2 = this._slider.value + num;
            if (num2 >= this._slider.maxValue)
            {
                this._slider.value = this._slider.minValue;
            }
            else
            {
                this._slider.value = num2;
            }
        }


        private void DecreaseOnly()
        {
            if (this.sliderValue < this._slider.value)
            {
                this.DoubleWay();
                return;
            }
            float num = this.tweenSpeed * Time.deltaTime;
            float num2 = this._slider.value - num;
            if (num2 <= this._slider.minValue)
            {
                this._slider.value = this._slider.maxValue;
            }
            else
            {
                this._slider.value = num2;
            }
        }

        private void DoubleWay()
        {
            float num = this.sliderValue - this._slider.value;
            float num2 = this.tweenSpeed * Time.deltaTime;
            if (num2 > Mathf.Abs(num))
            {
                this._slider.value = this.sliderValue;
                this.IsNeedTween = false;
            }
            else if (num > 0f)
            {
                this._slider.value += num2;
            }
            else
            {
                this._slider.value -= num2;
            }
        }




    }
}

